// internal/apps/auth/controllers/role_controller.go
package controllers

import (
	"star-go-app/internal/apps/auth/serializers"
	"star-go-app/internal/apps/auth/services"
	"star-go-app/pkg/common/utils/response"
	"strconv"

	"github.com/gin-gonic/gin"
)

// RoleController 角色控制器
type RoleController struct {
	roleService services.RoleService
}

// NewRoleController 创建角色控制器实例
func NewRoleController() *RoleController {
	return &RoleController{
		roleService: services.NewRoleService(),
	}
}

// CreateRole 创建角色
// @Summary 创建角色
// @Description 创建新的角色，支持JSON和表单两种传参方式
// @Tags 角色管理
// @Accept json,x-www-form-urlencoded
// @Produce json
// @Param request body serializers.CreateRoleRequest true "创建角色请求(JSON格式)"
// @Param name formData string false "角色名称(表单格式)"
// @Param code formData string false "角色编码(表单格式)"
// @Param description formData string false "角色描述(表单格式)"
// @Param permissions formData []string false "角色权限(表单格式)"
// @Success 200 {object} response.Response{data=serializers.RoleResponse} "创建成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Failure 409 {object} response.Response "角色编码或名称已存在"
// @Router /api/auth/roles [post]
func (ctrl *RoleController) CreateRole(c *gin.Context) {
	var req serializers.CreateRoleRequest
	if err := c.ShouldBind(&req); err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "请求参数错误", err.Error())
		return
	}

	role, err := ctrl.roleService.CreateRole(&req)
	if err != nil {
		response.FailWithMessage(c, response.ERROR, "创建角色失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "角色创建成功", role)
}

// GetRoleList 获取角色列表
// @Summary 获取角色列表
// @Description 分页获取角色列表，支持按名称和编码搜索
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param name query string false "角色名称"
// @Param code query string false "角色编码"
// @Success 200 {object} response.Response{data=serializers.RoleListResponse} "获取成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Router /api/auth/roles [get]
func (ctrl *RoleController) GetRoleList(c *gin.Context) {
	var req serializers.RoleListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "请求参数错误", err.Error())
		return
	}

	result, err := ctrl.roleService.GetRoleList(&req)
	if err != nil {
		response.FailWithMessage(c, response.ERROR, "获取角色列表失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "获取角色列表成功", result)
}

// GetRoleByID 根据ID获取角色详情
// @Summary 根据ID获取角色详情
// @Description 根据角色ID获取角色的详细信息
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param id path int true "角色ID"
// @Success 200 {object} response.Response{data=serializers.RoleResponse} "获取成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Failure 404 {object} response.Response "角色不存在"
// @Router /api/auth/roles/{id} [get]
func (ctrl *RoleController) GetRoleByID(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "无效的角色ID", "角色ID必须是数字")
		return
	}

	role, err := ctrl.roleService.GetRoleByID(uint(id))
	if err != nil {
		response.FailWithMessage(c, response.NOT_FOUND, "获取角色失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "获取角色成功", role)
}

// UpdateRole 部分更新角色
// @Summary 部分更新角色
// @Description 部分更新角色信息，支持JSON和表单两种传参方式
// @Tags 角色管理
// @Accept json,x-www-form-urlencoded
// @Produce json
// @Param id path int true "角色ID"
// @Param request body serializers.UpdateRoleRequest true "更新角色请求(JSON格式)"
// @Param name formData string false "角色名称(表单格式)"
// @Param code formData string false "角色编码(表单格式)"
// @Param description formData string false "角色描述(表单格式)"
// @Param permissions formData []string false "角色权限(表单格式)"
// @Success 200 {object} response.Response{data=serializers.RoleResponse} "更新成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Failure 404 {object} response.Response "角色不存在"
// @Failure 409 {object} response.Response "角色编码或名称已存在"
// @Router /api/auth/roles/{id} [put]
func (ctrl *RoleController) UpdateRole(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "无效的角色ID", "角色ID必须是数字")
		return
	}

	var req serializers.UpdateRoleRequest
	if err := c.ShouldBind(&req); err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "请求参数错误", err.Error())
		return
	}

	role, err := ctrl.roleService.UpdateRole(uint(id), &req)
	if err != nil {
		response.FailWithMessage(c, response.ERROR, "更新角色失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "角色更新成功", role)
}

// UpdateRoleWhole 完整更新角色
// @Summary 完整更新角色
// @Description 完整更新角色信息，支持JSON和表单两种传参方式
// @Tags 角色管理
// @Accept json,x-www-form-urlencoded
// @Produce json
// @Param id path int true "角色ID"
// @Param request body serializers.UpdateRoleWholeRequest true "完整更新角色请求(JSON格式)"
// @Param name formData string false "角色名称(表单格式)"
// @Param code formData string false "角色编码(表单格式)"
// @Param description formData string false "角色描述(表单格式)"
// @Param permissions formData []string false "角色权限(表单格式)"
// @Success 200 {object} response.Response{data=serializers.RoleResponse} "更新成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Failure 404 {object} response.Response "角色不存在"
// @Failure 409 {object} response.Response "角色编码或名称已存在"
// @Router /api/auth/roles/{id}/whole [put]
func (ctrl *RoleController) UpdateRoleWhole(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "无效的角色ID", "角色ID必须是数字")
		return
	}

	var req serializers.UpdateRoleWholeRequest
	if err := c.ShouldBind(&req); err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "请求参数错误", err.Error())
		return
	}

	role, err := ctrl.roleService.UpdateRoleWhole(uint(id), &req)
	if err != nil {
		response.FailWithMessage(c, response.ERROR, "更新角色失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "角色更新成功", role)
}

// DeleteRole 删除角色
// @Summary 删除角色
// @Description 根据ID删除角色
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param id path int true "角色ID"
// @Success 200 {object} response.Response "删除成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Failure 404 {object} response.Response "角色不存在"
// @Router /api/auth/roles/{id} [delete]
func (ctrl *RoleController) DeleteRole(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "无效的角色ID", "角色ID必须是数字")
		return
	}

	err = ctrl.roleService.DeleteRole(uint(id))
	if err != nil {
		response.FailWithMessage(c, response.ERROR, "删除角色失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "角色删除成功", nil)
}

// DeleteRolePermanently 永久删除角色
// @Summary 永久删除角色
// @Description 根据ID永久删除角色
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param id path int true "角色ID"
// @Success 200 {object} response.Response "删除成功"
// @Failure 400 {object} response.Response "请求参数错误"
// @Failure 404 {object} response.Response "角色不存在"
// @Router /api/auth/roles/{id}/true [delete]
func (ctrl *RoleController) DeleteRolePermanently(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.FailWithMessage(c, response.INVALID_PARAMS, "无效的角色ID", "角色ID必须是数字")
		return
	}

	err = ctrl.roleService.DeleteRolePermanently(uint(id))
	if err != nil {
		response.FailWithMessage(c, response.ERROR, "永久删除角色失败", err.Error())
		return
	}

	response.SuccessWithMessage(c, "角色永久删除成功", nil)
}
